package com.zc.auth.security.core.authentication;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.zc.auth.security.core.properties.JwtProperties;
import com.zc.commons.user.dto.AuthorizedUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.BeanUtils;

import java.util.Date;
import java.util.HashMap;

/**
 * jwt处理
 *
 * @author zcj
 * @version 1.0.0
 * @date 2022/1/13 11:14
 */
public class JsonWebTokenService {

    /**
     * 用于signature（签名）部分解密
     */
    private String primaryKey;

    /**
     * 签发者
     */
    private String iss;

    /**
     * 添加角色的key
     */
    private String roleClaims;

    /**
     * 添加用户的key
     */
    private String userClaims;

    /**
     * 过期时间是3600秒，既是1个小时
     */
    private Integer expiration;

    /**
     * 选择了记住我之后的过期时间为7天
     */
    private Integer expirationRemember;

    /**
     * 绑定参数
     *
     * @param jwtProperties
     * @return
     */
    public JsonWebTokenService bindValues(JwtProperties jwtProperties) {
        BeanUtils.copyProperties(jwtProperties, this);
        return this;
    }


    /**
     * 根据用户和角色生成token
     *
     * @param currentAuthUser
     * @param rememberMe
     * @return
     */
    public String generateJwtToken(AuthorizedUser authorizedUser, boolean rememberMe) {
        int expiration = rememberMe ? this.expirationRemember : this.expiration;

        HashMap<String, Object> map = new HashMap<>();
        map.put(userClaims, JSON.toJSONString(authorizedUser, SerializerFeature.WriteMapNullValue));

        String jwtToken = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, this.primaryKey)
                .setSubject(authorizedUser.getAccount())
                .setClaims(map)
                .setIssuer(iss)
                .setIssuedAt(new Date())
                .setExpiration(null)
                .compact();
        return jwtToken;
    }

    /**
     * 获取token
     *
     * @param token
     * @return
     */
    public Claims getTokenBody(String str) {
        return Jwts.parser()
                .setSigningKey(this.primaryKey)
                .parseClaimsJws(str)
                .getBody();
    }

    public String getUserClaims() {
        return userClaims;
    }


}
